package com.ant.common.interceptor;

import com.ant.business.system.service.UserTokenService;
import com.ant.business.system.vo.UserVo;
import com.ant.common.annotation.AuthIgnore;
import com.ant.common.exceptions.BusinessException;
import com.ant.common.utils.FastMap;
import com.ant.common.utils.StringUtil;
import com.ant.common.utils.UserThreadLocal;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;

@Component
@Slf4j
public class ReqInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private UserTokenService userTokenService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String errorCode = "4001";
        try {
            if ("OPTIONS".equals(request.getMethod())) {
                return true;
            }

            String requestURI = request.getRequestURI();
            log.info("request path ：" + requestURI);

            Object errorObj = request.getAttribute("isError");
            if (errorObj instanceof Boolean) {
                Boolean error = (Boolean) errorObj;
                if (error) {
                    String errorMsg = request.getAttribute("errorMsg").toString();
                    errorCode = request.getAttribute("errorCode").toString();
                    throw new BusinessException(errorMsg);
                }
            }

            if (requestURI.contains("swagger") || requestURI.contains("static") || requestURI.contains("webSocket")) {
                return true;
            }

            if ("/ant/error".equals(requestURI)) {
                throw new BusinessException("bad request");
            }
            //忽视token验证
            AuthIgnore authIgnore = null;
            if (handler instanceof HandlerMethod) {
                authIgnore = ((HandlerMethod) handler).getMethodAnnotation(AuthIgnore.class);
            }

            //如果有@TradeTouchAuthIgnore注解，则不验证token
            if (authIgnore != null) {
                return true;
            }

            String token = request.getHeader("token");
            if (StringUtil.isEmpty(token)) {
                throw new BusinessException("token is empty");
            }

            ServletContext sc = request.getSession().getServletContext();
            AbstractApplicationContext cxt = (AbstractApplicationContext) WebApplicationContextUtils.getWebApplicationContext(sc);
            if(cxt != null) {
                if (userTokenService == null) {
                    userTokenService = (UserTokenService) cxt.getBean("userTokenService");
                }
            }

            UserVo user = userTokenService.getUserInfo(token);
            if (Objects.isNull(user)) {
                throw new BusinessException("user info is null");
            }

            UserThreadLocal.setUser(user);
            return true;
        } catch (Exception e) {
            log.error("auth error ：", e);
            throw new BusinessException(errorCode, "auth error : " + e.getMessage());
        }
    }
}
